﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Web.Hosting;
using TomNet.IMSC.Core.Contracts.Organization;
using TomNet.IMSC.Model.DbModels.Organization;

namespace TomNet.IMSC.Web.Common
{
    public class BaseWebApiExt
    {
        public static Dictionary<string, string> DicToken = new Dictionary<string, string>();
        public static Dictionary<string, string> StaffDicToken = new Dictionary<string, string>();


        static string Pass1 = "P@ssw0rd";
        static string Pass2 = "P@ssw0rd";


        /// <summary>
        /// 获取用户新的token--同时更新静态变量  和 数据库
        /// </summary>
        /// <returns></returns>
        public static string GetNewToken(IUsersLoginContract UsersLoginContract, int userId)
        {
            var userData = UsersLoginContract.GetByKey(userId);

            byte[] idByte = BitConverter.GetBytes(userData.UserID);
            byte[] nameByte = BitConverter.GetBytes(long.Parse(userData.LoginName));
            byte[] tokenArray = Encoding.Default.GetBytes(Guid.NewGuid().ToString());

            int len = idByte.Length + nameByte.Length + tokenArray.Length;
            byte[] array = new byte[len];

            Array.Copy(idByte, 0, array, 0, idByte.Length);
            Array.Copy(nameByte, 0, array, idByte.Length, nameByte.Length);
            Array.Copy(tokenArray, 0, array, idByte.Length + nameByte.Length, tokenArray.Length);

            var newtoken = Convert.ToBase64String(array);

            userData.Token = newtoken;

            //字典是否存在
            if (DicToken == null)
            {
                DicToken = new Dictionary<string, string>();
            }

            if (DicToken.Where(d => d.Key == userData.LoginName).Count() > 0)
            {
                DicToken[userData.LoginName] = userData.Token; //替换
            }
            else
            {
                DicToken.Add(userData.LoginName, userData.Token);//加载
            }

            UsersLoginContract.UpdateDirect(userData.Id, m => new UsersLogin { Token = userData.Token });//更新库

            return userData.Token;
        }

        /// <summary>
        /// 获取用户新的token--同时更新静态变量  和 数据库
        /// </summary>
        /// <returns></returns>
        public static string StaffGetNewToken(IStaffLoginContract StaffLoginContract, int staffLoginId)
        {
            var staffLoginModel = StaffLoginContract.GetByKey(staffLoginId);

            byte[] idByte = BitConverter.GetBytes(staffLoginModel.StaffID);
            byte[] nameByte = BitConverter.GetBytes(long.Parse(staffLoginModel.LoginName));
            byte[] tokenArray = Encoding.Default.GetBytes(Guid.NewGuid().ToString());

            int len = idByte.Length + nameByte.Length + tokenArray.Length;
            byte[] array = new byte[len];

            Array.Copy(idByte, 0, array, 0, idByte.Length);
            Array.Copy(nameByte, 0, array, idByte.Length, nameByte.Length);
            Array.Copy(tokenArray, 0, array, idByte.Length + nameByte.Length, tokenArray.Length);

            var newtoken = Convert.ToBase64String(array);

            staffLoginModel.Token = newtoken;

            //字典是否存在
            if (StaffDicToken == null)
            {
                StaffDicToken = new Dictionary<string, string>();
            }

            if (StaffDicToken.Where(d => d.Key == staffLoginModel.LoginName).Count() > 0)
            {
                StaffDicToken[staffLoginModel.LoginName] = staffLoginModel.Token; //替换
            }
            else
            {
                StaffDicToken.Add(staffLoginModel.LoginName, staffLoginModel.Token);//加载
            }

            StaffLoginContract.UpdateDirect(staffLoginModel.Id, m => new StaffLogin { Token = staffLoginModel.Token });//更新库

            return staffLoginModel.Token;
        }

        /// <summary>
        /// 获取用户真实的token--解密DES
        /// </summary>
        /// <returns></returns>
        public static string GetRealityToken(string token)
        {

            byte[] inputByteArray = Convert.FromBase64String(token);
            using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
            {
                des.Key = ASCIIEncoding.ASCII.GetBytes(Pass1);
                des.IV = ASCIIEncoding.ASCII.GetBytes(Pass2);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(inputByteArray, 0, inputByteArray.Length);
                    cs.FlushFinalBlock();
                    cs.Close();
                }
                string str = Encoding.UTF8.GetString(ms.ToArray());
                ms.Close();
                return str;
            }
        }

        /// <summary>
        /// 获取用户加密的token--加密DES
        /// </summary>
        /// <returns></returns>
        public static string ToCiphertextToken(string token)
        {

            using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
            {
                byte[] inputByteArray = Encoding.UTF8.GetBytes(token);
                des.Key = ASCIIEncoding.ASCII.GetBytes(Pass1);
                des.IV = ASCIIEncoding.ASCII.GetBytes(Pass2);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(inputByteArray, 0, inputByteArray.Length);
                    cs.FlushFinalBlock();
                    cs.Close();
                }
                string str = Convert.ToBase64String(ms.ToArray());
                ms.Close();
                return str;
            }
        }

        /// <summary>
        /// 根据token 解析token内容
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public static bool GetUserByToken(string token, UsersLogin userData)
        {
            MemoryStream ms = new MemoryStream(Convert.FromBase64String(token));
            byte[] bt = ms.ToArray();
            int nId = BitConverter.ToInt32(bt, 0);
            long nName = BitConverter.ToInt64(bt, sizeof(int));

            if (nId == userData.UserID && nName.ToString() == userData.LoginName)
            {
                if (DicToken == null)
                {
                    DicToken = new Dictionary<string, string>();
                }

                if (DicToken.Where(d => d.Key == userData.LoginName).Count() > 0)
                {
                    DicToken[userData.LoginName] = userData.Token; //替换
                }
                else
                {
                    DicToken.Add(userData.LoginName, userData.Token);//加载
                }

                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 根据token 解析token内容
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public static bool GetStaffByToken(string token, StaffLogin staffData)
        {
            MemoryStream ms = new MemoryStream(Convert.FromBase64String(token));
            byte[] bt = ms.ToArray();
            int nId = BitConverter.ToInt32(bt, 0);
            long nName = BitConverter.ToInt64(bt, sizeof(int));

            if (nId == staffData.StaffID && nName.ToString() == staffData.LoginName)
            {
                if (StaffDicToken == null)
                {
                    StaffDicToken = new Dictionary<string, string>();
                }

                if (StaffDicToken.Where(d => d.Key == staffData.LoginName).Count() > 0)
                {
                    StaffDicToken[staffData.LoginName] = staffData.Token; //替换
                }
                else
                {
                    StaffDicToken.Add(staffData.LoginName, staffData.Token);//加载
                }

                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 解析Token获取UserID
        /// </summary>
        /// <returns></returns>
        public static int GetUserIDByToken()
        {
            string tokenStr = HttpContext.Current.Request.Headers["Token"];//获取Token

            tokenStr = GetRealityToken(tokenStr);//解密Token

            MemoryStream ms = new MemoryStream(Convert.FromBase64String(tokenStr));
            byte[] bt = ms.ToArray();
            int nId = BitConverter.ToInt32(bt, 0);//获得UserID

            return nId;
        }

        /// <summary>
        /// 解析Token获取StaffID
        /// </summary>
        /// <returns></returns>
        public static int GetStaffIDByToken()
        {
            string tokenStr = HttpContext.Current.Request.Headers["Token"];//获取Token

            tokenStr = GetRealityToken(tokenStr);//解密Token

            MemoryStream ms = new MemoryStream(Convert.FromBase64String(tokenStr));
            byte[] bt = ms.ToArray();
            int nId = BitConverter.ToInt32(bt, 0);//获得UserID

            return nId;
        }

        /// <summary>
        /// Api 登录
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="Pass"></param>
        /// <returns></returns>
        public static UsersLogin ApiLogin(IUsersLoginContract UsersLoginContract, string userName, string Pass)
        {

            var user = UsersLoginContract.Entities.Where(d => d.LoginName == userName && d.LoginPass == Pass && !d.IsDeleted);
            if (user != null && user.Count() > 0)
            {
                return user.FirstOrDefault();
            }
            else
            {
                return null;
            }

        }

        /// <summary>
        /// Staff Api 登录
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="Pass"></param>
        /// <returns></returns>
        public static StaffLogin StaffApiLogin(IStaffLoginContract StaffLoginContract, string userName, string Pass)
        {

            var staff = StaffLoginContract.Entities.Where(d => d.LoginName == userName && d.LoginPass == Pass);
            if (staff != null && staff.Count() > 0)
            {
                return staff.FirstOrDefault();
            }
            else
            {
                return null;
            }

        }

        /// <summary>
        /// 转换实体
        /// </summary>
        /// <param name="oldModel"></param>
        /// <param name="newModel"></param>
        /// <returns></returns>
        public static object ConvertModel(object oldModel, object newModel)
        {

            PropertyInfo[] properties = oldModel.GetType().GetProperties();

            foreach (var p in properties)
            {
                var value = p.GetValue(oldModel, null);
                if (value != GetDefault(p.GetType()))
                    p.SetValue(newModel, value, null);
            }
            return newModel;
        }

        /// <summary>
        /// 转换实体用函数
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static object GetDefault(Type type)
        {
            if (type.IsValueType)
            {
                return Activator.CreateInstance(type);
            }
            return null;
        }

        /// <summary>
        /// 转换星期
        /// </summary>
        /// <param name="DayOfWeek"></param>
        /// <returns></returns>
        public static string Week(DayOfWeek DayOfWeek)
        {
            string[] weekdays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
            string week = weekdays[Convert.ToInt32(DayOfWeek)];

            return week;
        }


        /// <summary>
        /// 获取项目文件根目录
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static string GetMapPath(string path)
        {
            var phicyPath = HostingEnvironment.MapPath(path);

            return phicyPath;
        }

        /// <summary>
        /// 读取指定文件
        /// </summary>
        /// <param name="path"></param>
        public static string Read(string path)
        {
            try
            {
                StreamReader sr = new StreamReader(path, Encoding.Default);
                return sr.ReadToEnd();
            }
            catch (IOException e)
            {
                Console.WriteLine(e.ToString());
                return "";
            }
        }
    }
}